<template>
  <view class="popup" @touchmove.stop.prevent>
    <view
      class="overlay"
      @click="clickOverlay"
      :style="[showOverlay, { transitionDuration: `${duration}s` }]"
    />
    <view
      class="panel" :class="'popup-panel--' + position"
      :style="[panelStyle, showPopup, { transform, transition: `${duration}s` }]"
    >
      <slot></slot>
    </view>
  </view>
</template>

<script>
export default {
  name: "Popup",
  props: {
    // 是否显示
    value: {
      type: Boolean,
      default: false,
    },
    // 弹出位置，默认居中弹出，可以设置为 top、bottom、left、right
    position: {
      type: String,
      default: "center",
    },
    // 面板样式
    styles: {
      type: Object,
      default: () => {
        return {}
      }
    },
    // 动画时长，单位秒
    duration: {
      type: Number,
      default: 0.3,
    },
    // 弹出缩放系数（只有 position = center 时生效）
    scale: {
      type: Number,
      default: 1
    },
    // 是否在点击遮罩层后关闭
    clickOverlayClose: {
      type: Boolean,
      default: true,
    },
    // 遮罩透明度
    overlayOpacity: {
      type: Number,
      default: 0.65
    },
    // 增加高度（适用于元素超出 Panel）
    heightAdd: {
      type: Number,
      default: 0
    }
  },
  computed: {
    panelStyle() {
      return Object.assign(
        {
          height: "600rpx",
          background: "#fff",
        },
        this.styles
      )
    },
  },
  watch: {
    value(show) {
      let { position, panelStyle } = this
      let { width, height } = panelStyle
      this.resetPopupAnimation(width, height, position)
      show ? this.openPopup(position) : this.closePopup(position)
    },
  },
  data() {
    return {
      showOverlay: {
        display: "none"
      },
      showPopup: {
        display: "none"
      },
      transform: ""
    }
  },
  methods: {
    // 打开弹窗
    openPopup(position) {
      let tf = ''
      this.showPopup = {}
      this.showOverlay = {}

      if (position === "center") {
        this.showPopup = { opacity: 0 }
      }

      setTimeout(() => {
        if (position === "left" || position === "right") {
          tf = `translateX(0)`
        } else if (position === "bottom" || position === "top") {
          tf = `translateY(0)`
        }else if(position === "center") {
          tf = `scale(${this.scale})`
        }
        this.transform = tf
        this.showOverlay = { backgroundColor: `rgba(0, 0, 0, ${this.overlayOpacity})` }
        this.opened()
      }, 50)
      
      setTimeout(() => {
        if(position === "center") {
          this.transform = `scale(1)`
        }
      }, this.duration * 1000)

      setTimeout(() => {
        this.showPopup = { display: "block" }
      }, 100)
    },
    // 关闭弹窗
    closePopup(position) {
      this.showOverlay = {
        backgroundColor: "rgba(0, 0, 0, 0)"
      }

      if (position === "center") {
        this.showPopup = { opacity: 0 }
      }

      setTimeout(() => {
        this.$set(this.showPopup, "display", "none")
        this.showOverlay = {
          display: "none"
        }
      }, this.duration * 1000)
    },
    // 重置弹窗动画
    resetPopupAnimation(width, height, position) {
      let tX = ""
      if(position === 'bottom' && this.heightAdd) {
        height = parseFloat(height) + this.heightAdd + 'rpx'
      }
      switch (position) {
        case "center":
          tX = `scale(0)`
          break
        case "left":
          tX = `translateX(-${width})`
          break
        case "right":
          tX = `translateX(${width})`
          break
        case "top":
          tX = `translateY(-${height})`
          break
        case "bottom":
          tX = `translateY(${height})`
          break
      }
      this.transform = tX
    },
    // 打开弹出层且动画结束后触发
    opened() {
      setTimeout(() => {
        this.$emit("opened")
      }, this.duration * 1000)
    },
    // 点击遮罩层时触发
    clickOverlay() {
      if (this.clickOverlayClose) {
        this.$emit("clickOverlay")
        this.$emit("input", false)
        this.close()
      }
    },
    // 关闭弹出层时触发
    close() {
      this.$emit("close")
      this.closed()
    },
    // 关闭弹出层且动画结束后触发
    closed() {
      setTimeout(() => {
        this.$emit("closed")
      }, this.duration * 1000)
    },
    // 设置状态栏文字颜色
    setStatusBarColor(color) {
      // #ifdef APP-PLUS
      plus.navigator.setStatusBarStyle(color)
      // #endif
    }
  },
}
</script>

<style lang="scss" scoped>
  @import  './index.scss';
</style>